<?php

namespace App\Jobs;

use App\Http\Traits\WriteUserMoneyLog;
use App\Models\ProductsExchange;
use App\Models\UserAssets;
use App\Models\UserExchange;
use App\Models\UserExchangeRecord;
use App\Models\UserMoneyLog;
use App\Models\WalletCode;
use App\Services\MatchEngineService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class OrderHandle implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, WriteUserMoneyLog;

    public $result;

    /**
     * Create a new job instance.
     * @param $result
     * @return void
     */
    public function __construct($result)
    {
        //
        $this->result = $result;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // php artisan queue:work --queue=OrderHandle --sleep=3 --tries=1
        //echo 'OrderHandle', PHP_EOL;

        try {
            //
            //需要更新的单子
            $updateArr = $this->result['data']['updateArr'];
            //匹配上的单子  实时成交
            $matchArr = $this->result['data']['matchArr'];
            //新生成的单子
            $newArr = $this->result['data']['newArr'];

            if (!empty($matchArr)) {
                $this->doMatchArr($matchArr);
            }

            if (!empty($updateArr)) {
                $this->doUpdateArr($updateArr);
            }

            if (!empty($newArr)) {

            }
        } catch (\Exception $e) {
            $log = [
                'OrderHandle' => $e->getMessage(),
                'data'        => $this->result
            ];
            Log::error(json_encode($log, JSON_UNESCAPED_UNICODE));
            echo $e->getMessage();
        }

        /*
            "updateArr" => array:2 [
              0 => array:3 [
                "order_id" => 44
                "quantity" => 0.002
                "sellout" => 1
              ]
              1 => array:3 [
                "order_id" => 45
                "quantity" => 0.002
                "sellout" => 1
              ]
            ]
            "matchArr" => array:1 [
              0 => array:8 [
                "sell_id" => 5
                "buy_id" => "5"
                "price" => "710000000000"
                "quantity" => 0.002
                "side" => "ask"
                "market" => "btc/usdt"
                "sell_order" => 45
                "buy_order" => "44"
              ]
            ]
            "newArr" => []
            "rstArr" => []
         */
    }


    //更新成交数量和成交均价
    private function doMatchArr(array $matchArr): void
    {

        foreach ($matchArr as $item => $value) {
            $buy_order = UserExchange::find($value['buy_order']);
            $sell_order = UserExchange::find($value['sell_order']);

            // 成交均价 = (已成交价*已成交数量 + 本次成交价*本次成交数量) / (已成交数量+本次成交数量)
            $cjprice = ($value['price'] * $value['quantity'] + $buy_order->cjnum * $buy_order->cjprice) / ($value['quantity'] + $buy_order->cjnum);
            $buy_order->cjprice = $cjprice;
            $buy_order->cjnum += $value['quantity'];
            $buy_order->save();

            $cjprice = ($value['price'] * $value['quantity'] + $sell_order->cjnum * $sell_order->cjprice) / ($value['quantity'] + $sell_order->cjnum);
            $sell_order->cjprice = $cjprice;
            $sell_order->cjnum += $value['quantity'];
            $sell_order->save();


        }
    }

    //更新成交状态
    private function doUpdateArr(array $updateArr): void
    {
        foreach ($updateArr as $item => $value) {
            $orderInfo = UserExchange::find($value['order_id']);
            //该订单已完成
            if ($value['sellout'] == 1) {
                $orderInfo->status = UserExchangeRecord::OVER_TRANS;
//                UserExchange::destroy($orderInfo->id);
//                unset($orderInfo->id, $orderInfo->created_at, $orderInfo->updated_at);
//                $result = UserExchangeRecord::create($orderInfo->toArray());

                if ($orderInfo->uid != 0){
                    if ($orderInfo->type == 2) {
                        //卖单结算
                        $total = $orderInfo->cjprice * $orderInfo->cjnum;

                        // 手续费
                        $feeRate = WalletCode::getExchangeFeeById($orderInfo->r_wid) * 0.01;
                        $fee = $total * $feeRate;
                        $total -= $fee;
                        $asset = UserAssets::getBalance($orderInfo->uid, $orderInfo->r_wid, true);
                        $this->writeBalanceLog($asset, 0, $orderInfo->r_wid, $total, UserMoneyLog::EXCHANGE, '币币交易卖出收益');
                    } else {
                        //买单结算  可能会涉及退一部分钱
                        $asset = UserAssets::getBalance($orderInfo->uid, $orderInfo->l_wid, true);

                        // 手续费
                        $feeRate = WalletCode::getExchangeFeeById($orderInfo->l_wid) * 0.01;
                        $fee = $orderInfo->cjnum * $feeRate;
                        $cjnum = $orderInfo->cjnum - $fee;
                        $this->writeBalanceLog($asset, 0, $orderInfo->l_wid, $cjnum, UserMoneyLog::EXCHANGE, '币币买入收益');

                        $backPrice = $orderInfo->totalprice - ($orderInfo->cjprice * $orderInfo->cjnum);
                        if ($backPrice > 0) {
                            $asset = UserAssets::getBalance($orderInfo->uid, $orderInfo->r_wid, true);
                            $this->writeBalanceLog($asset, 0, $orderInfo->r_wid, $backPrice, UserMoneyLog::EXCHANGE, '币币买入交易退还');
                        }
                    }
                }else{
                    //机器人账户
                    $fee = 0;
                }

                $orderInfo->fee = $fee;
            } else {
                $orderInfo->status = UserExchangeRecord::ING_TRANS;
            }

            $orderInfo->save();
        }
    }

    //TODO 推送盘口
    private function publishDepth($code)
    {
        try {
            $params = json_encode([
                'type' => 'handicap',
                'data' => [
                    'market' => $code, //交易市场
                    'slice'  => 200, //
                ]
            ]);

            $result = MatchEngineService::run($params);
            if ($result['code'] != 1) {
                throw new \Exception($result['err']);
            }

            return __return($this->successStatus, '获取成功', $result['data']);
        } catch (\Exception $e) {
            return __return($this->errStatus, $e->getMessage());
        }
    }


}
